package org.Yiran.timetale_re.item.items;

import net.minecraft.client.gui.screens.Screen;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import org.Yiran.timetale_re.item.base.DescriptiveItem;
import org.Yiran.timetale_re.item.runeblueprint.base.RuneBlueprintItem;
import org.Yiran.timetale_re.menu.RuneBlueprintBookMenu;
import org.Yiran.timetale_re.network.NetworkChannel;
import org.Yiran.timetale_re.network.SCResponsePacket;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 符文图纸手册物品类
 * <p>
 * 该类表示符文图纸手册物品，继承自DescriptiveItem基类。
 * 支持以下功能：
 * 1. 右键查看图册内容（图纸模型）
 * 2. Shift+右键打开完整图册容器GUI
 * 3. 按住Shift键显示图册中包含的图纸信息
 * </p>
 */
public class RuneBlueprintBookItem extends DescriptiveItem {
    
    // ============================== 构造方法 ==============================
    
    /**
     * 构造函数 - 创建一个新的符文图纸手册物品
     * 
     * @param properties 物品属性
     */
    public RuneBlueprintBookItem(Properties properties) {
        super(properties);
    }

    // ============================== 使用方法 ==============================
    
    /**
     * 处理物品使用事件
     * <p>
     * 根据是否按下Shift键来决定执行的操作：
     * - 按下Shift键：打开完整图册容器GUI
     * - 未按下Shift键：查看图册内容（图纸模型）
     * </p>
     * 
     * @param level 世界对象
     * @param player 玩家对象
     * @param hand 交互手部
     * @return 交互结果
     */
    @Override
    public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level level, Player player, @NotNull InteractionHand hand) {
        ItemStack stack = player.getItemInHand(hand);

        // 检查是否按下Shift键
        if (Screen.hasShiftDown()) {
            // Shift+右键打开完整图册容器
            return handleOpenGui(level, player, stack);
        } else {
            // 右键查看图册内容（图纸模型）
            return handleViewModels(level, player, stack);
        }
    }

    // ============================== 交互处理方法 ==============================
    
    /**
     * 处理查看模型操作
     * <p>
     * 在服务端发送数据包到客户端打开模型查看界面
     * </p>
     * 
     * @param level 世界对象
     * @param player 玩家对象
     * @param stack 符文图纸手册物品堆
     * @return 交互结果
     */
    private InteractionResultHolder<ItemStack> handleViewModels(Level level, Player player, ItemStack stack) {
        if (!level.isClientSide) {
            // 在服务端发送数据包到客户端打开模型查看界面
            NetworkChannel.CHANNEL.send(
                    PacketDistributor.PLAYER.with(() -> (ServerPlayer) player),
                    new SCResponsePacket.RuneBlueprintBookViewPacket(stack)
            );
        }
        return InteractionResultHolder.success(stack);
    }

    /**
     * 处理GUI打开逻辑
     * <p>
     * 在服务端打开GUI界面
     * </p>
     * 
     * @param level 世界对象
     * @param player 玩家对象
     * @param stack 符文图纸手册物品堆
     * @return 交互结果
     */
    private InteractionResultHolder<ItemStack> handleOpenGui(Level level, Player player, ItemStack stack) {
        if (!level.isClientSide) {
            // 在服务端打开GUI界面
            NetworkHooks.openScreen((ServerPlayer) player, createMenuProvider(), buf -> buf.writeItem(stack));
        }
        return InteractionResultHolder.success(stack);
    }

    // ============================== 菜单提供器方法 ==============================
    
    /**
     * 创建菜单提供器
     * <p>
     * 用于创建符文图纸手册的菜单界面
     * </p>
     * 
     * @return 菜单提供器实例
     */
    private MenuProvider createMenuProvider() {
        return new MenuProvider() {
            @Override
            public @NotNull Component getDisplayName() {
                // 返回显示名称
                return Component.translatable("item.timetale_re.rune_blueprint_book");
            }

            @Override
            public AbstractContainerMenu createMenu(int windowId, @NotNull Inventory playerInventory, @NotNull Player player) {
                // 创建符文图纸手册菜单
                return new RuneBlueprintBookMenu(windowId, playerInventory, player.getMainHandItem());
            }
        };
    }

    // ============================== 工具提示方法 ==============================
    
    /**
     * 添加工具提示信息
     * <p>
     * 在客户端环境中为物品添加工具提示信息。
     * 如果按住Shift键，会显示图册中的内容详情。
     * </p>
     * 
     * @param stack 物品堆栈
     * @param level 世界对象
     * @param tooltip 工具提示列表
     * @param flag 工具提示标志
     */
    @Override
    @OnlyIn(Dist.CLIENT)
    public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @NotNull List<Component> tooltip, @NotNull TooltipFlag flag) {
        // 调用父类方法添加基础描述
        super.appendHoverText(stack, level, tooltip, flag);

        // 如果按住Shift键，显示图册中的内容
        if (Screen.hasShiftDown()) {
            addBookContentsTooltip(stack, tooltip);
        }
    }

    /**
     * 添加图册内容工具提示
     * <p>
     * 从NBT数据中读取图册内容并添加到工具提示中
     * </p>
     * 
     * @param stack 物品堆栈
     * @param tooltip 工具提示列表
     */
    private void addBookContentsTooltip(ItemStack stack, List<Component> tooltip) {
        Map<String, Integer> blueprintCounts = new HashMap<>();

        // 从NBT数据中读取图册内容
        if (stack.getTag() != null && stack.hasTag() && stack.getTag().contains("BookInventory")) {
            CompoundTag bookInventoryTag = stack.getTag().getCompound("BookInventory");
            if (bookInventoryTag.contains("Items")) {
                ListTag itemsList = bookInventoryTag.getList("Items", 10);

                for (int i = 0; i < itemsList.size(); i++) {
                    CompoundTag itemTag = itemsList.getCompound(i);
                    ItemStack slotItem = ItemStack.of(itemTag);

                    if (slotItem.getItem() instanceof RuneBlueprintItem) {
                        // 获取符文类型并构造正确地显示名称
                        String runeType = RuneBlueprintItem.getRuneType(slotItem);
                        String displayName = "";

                        if (runeType != null && !runeType.isEmpty()) {
                            // 根据符文类型获取翻译键
                            String translationKey = "item.timetale_re." + runeType + "_rune_blueprint";
                            displayName = Component.translatable(translationKey).getString();
                        }

                        blueprintCounts.put(displayName, blueprintCounts.getOrDefault(displayName, 0) + slotItem.getCount());
                    }
                }
            }
        }

        // 添加内容信息到提示
        if (!blueprintCounts.isEmpty()) {
            tooltip.add(Component.literal("§8| §7图册内容:"));
            for (Map.Entry<String, Integer> entry : blueprintCounts.entrySet()) {
                String name = entry.getKey();
                int count = entry.getValue();
                tooltip.add(Component.literal("  §3" + name + " §7x" + count));
            }
        } else {
            tooltip.add(Component.literal("§8| §7图册内容: 空"));
        }
    }

    // ============================== 工具方法 ==============================
    
    /**
     * 检查物品是否为符文图纸
     * 
     * @param stack 要检查的物品堆
     * @return 如果是符文图纸返回true，否则返回false
     */
    public static boolean isRuneBlueprint(ItemStack stack) {
        return stack.getItem() instanceof RuneBlueprintItem;
    }
}